package com.JUC.cha09.sec04;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;

/**
 * 多线程并发调用一个类的初始化方法，如果未被初始化过，将执行初始化工作
 * 要求只能被初始化一次，只有一个线程操作成功
 */
class MyVar{//资源类

    private static final String name = "张顺";

    public volatile Boolean isInit = Boolean.FALSE;

    AtomicReferenceFieldUpdater<MyVar,Boolean> fieldUpdater = AtomicReferenceFieldUpdater.
            newUpdater(MyVar.class, Boolean.class, "isInit");

    public void init(MyVar myVar){

        if (fieldUpdater.compareAndSet(myVar, Boolean.FALSE, Boolean.TRUE)) {//不使用syn...保证原子性，并只针对某个字段，并且自定义字段
            System.out.println(Thread.currentThread().getName() + "\t" + "come in init method");
            System.out.println(Thread.currentThread().getName() + "\t" + "start initialize");

            // 暂停1秒钟线程，模拟处理业务
            try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); }

            System.out.println(Thread.currentThread().getName() + "\t" + "end init");
            System.out.println("当前状态" + "\t" + fieldUpdater.get(myVar));
        }else {//验证不对
            System.out.println(Thread.currentThread().getName() + "\t" + "no come in init method");
        }
    }
}

/**
 * 需求：
 * 多线程并发调用一个类的初始化方法，如果未被初始化过，将执行初始化工作
 * 需求只能被初始化一次，只有一个线程操作成功
 */
public class AtomicReferenceFieldUpdaterDemo {

    public static void main(String[] args) {
        MyVar myVar = new MyVar();

        for (int i = 0; i < 5; i++) {
            new Thread(() -> {
                myVar.init(myVar);
            }, String.valueOf(i)).start();
        }
    }
}
